using System;
using System.IO;
using System.Reflection;

using log4net;
using Tao.Lua;

namespace Playtime.RegionModule
{
	public class Utils
	{
		/// <summary>
		/// Reference the logger instance
		/// </summary>
		private static readonly ILog mLog = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

		public static string GetResourceAsString(string name)
		{
			foreach(string resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
			{
				if(resourceName.Contains(name))
					return new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)).ReadToEnd();
			}
			return null;	
		}	

		static Version mSystemVersion = null;
		public static bool IsMonoVersion(int major, int minor, int build, int revision)
		{
			
			if(mSystemVersion == null)
				foreach(Assembly a in AppDomain.CurrentDomain.GetAssemblies())
					if(a.GetName().Name == "System")
					{
						mSystemVersion = a.GetName().Version;
						break;
					}
			
			return IsRunningOnMono() && mSystemVersion <= new Version(major, minor, build, revision);
		}

		private static bool IsRunningOnMono()
		{
			return Type.GetType ("Mono.Runtime") != null;
		}
		
		#region various utility LUA functions for testing and debugging purposes
		public static void DumpTable(IntPtr luaState)
		{
			mLog.Debug("[SCLuaEngine] DumpTable");
			if(Lua.lua_type(luaState, -1) == Lua.LUA_TTABLE)
			{
				Lua.lua_pushnil(luaState);
				while(Lua.lua_next(luaState, -2) != 0)
				{
					string p1, p2;
					if(Lua.lua_type(luaState, -2) == Lua.LUA_TSTRING)
						p1 = '"' + Lua.luaL_checkstring(luaState, -2) + '"';
					else
						p1 = Lua.lua_typename(luaState, Lua.lua_type(luaState, -2));
					
					p2 = Lua.lua_typename(luaState, Lua.lua_type(luaState, -1));
       				/* uses 'key' (at index -2) and 'value' (at index -1) */
       				mLog.DebugFormat("[SCLuaEngine] {0} - {1}", p1, p2);

					/* removes 'value'; keeps 'key' for next iteration */
       				Lua.lua_pop(luaState, 1);
     			}
			}
			else
				mLog.Debug("[SCLuaEngine] DumpTable didn't find a table: " + Lua.luaL_typename(luaState, -1));
		}
		
		public static void DumpStack(IntPtr luaState)
		{
			mLog.DebugFormat("[SCLuaEngine] StackSize={0}", Lua.lua_gettop(luaState));
			for(int i=1; i<= Lua.lua_gettop(luaState); i++)
			{
				mLog.DebugFormat("[SCLuaEngine] Stack[{0}]={1}", i, Lua.luaL_typename(luaState, i));
				
			}
		}
		#endregion various utility LUA functions for testing and debugging purposes
	}
}

